/** @jsxImportSource @emotion/react */
import * as React from "react";
import { Link as RouterLink } from "../routing/Link";
import {PreloadedQuery, usePreloadedQuery, useRefetchableFragment} from "react-relay/hooks";
import {EditStorageContext} from "./StorageContext";
import RecordStarter from "./RecordStarter";
import {OriginalRecordMainQuery} from "./OriginalRecordMain";
import {RecordEditorMainInner$key} from "./__generated__/RecordEditorMainInner.graphql";

const graphql = require("babel-plugin-relay/macro");

//模板的版本号和相应代码维护管理是个问题；不是下载离线的，而是时刻web在线的文档格式；配套数据库数据加上配套模板才能拼凑出正式文档。要保留维护几年？有人还在用旧的。
//模板类型：支持主报告类型1个+分报告类型多个的情况，报告展示入口管理。模板版本号由后端管理。

interface RecordEditorMainProps {
    prepared: {
        template: any;   //该类型的模板 主入口：
        query: PreloadedQuery<typeof OriginalRecordMainQuery>;
    }
    routeData: any;
    children: React.ReactNode;
}
//首次render时刻template应该还没有获取到的，需要第二次render才能获得到template。
//RecordEditorOrPrint应该直接合体：
//【关键】这个才是真正可编辑原始记录的入口，右半边页面;
export default function RecordEditorMain( {
           prepared:{
               template: LibofLoadable, query: myQuery
           },
           routeData,
           children
 }:  RecordEditorMainProps
) {
    //省略掉了类型描述；原本usePreloadedQuery<OneAgreementMainQuery>();注意路由器loadQuery(注意配套描述类型定义的不一致？query: loadQuery(,OriginalRecordMainQuery,）;
    //【奇怪】
    const data = usePreloadedQuery(
        graphql`
            query RecordEditorMainQuery($id: ID! ) {
                getReport(id: $id) {
                    id,version,type
                    data
                    snapshot
                    modeltype,modelversion
                    isp{id}
                }
                ...RecordEditorMainInner
            }
        `,
        myQuery,         //类型应当是RecordEditorMainInner$key的
    );
    // const data = usePreloadedQuery<typeof OriginalRecordMainQuery>(  定义graphql公用的也是可能！
    //     OriginalRecordMainQuery,
    //     myQuery,
    // );
    // const { getReport: items }=data;

    /*
    旧版本加上EditStorageContext 右边组件编辑立刻能反馈给 左边组件=报告项目、列表的内容。
    跨越两个级别的路由Main组件页面，Context.Provider只能在共同最高一层组件上配上。
    这里和OriginalRecordMain都搞<EditStorageContext.Provider value={{ storage, setStorage }}居然能够互通，本来storage实例都是不一样的，不应该啊可能互通的。
    【揭秘】这里组件保存后，直接修改了Relay的客户端上缓存，对象缓存可就是整个APP共同的；所以右半边路由页面改了保存了后在左边路由组件不用Context也是可能互通=很快就能显示变化跟随数据的。
    虽然两个上下级路由页面，右边页面Relay变更后返回report的data数据，左边页面因为Relay针对同一个report的data就能立刻更新页面。不用EditStorageContext.Provider可以的！
    * */
    return (
      <LibofLoadable fallback={<h4>获取模板主入口</h4>} >
        {
            ( { reportTemplate, originalTemplate} :any) => {
                const originalNode= originalTemplate[routeData.params.verId];
                const reportNode= reportTemplate[routeData.params.verId];
                if(!reportNode || !originalNode)
                     throw new Error(`没有${routeData.params.template}类型${routeData.params.verId}版本${reportNode? '原始记录':'报告'}模板`);
                return (
                 <RecordEditorMainInner queryRef={data}
                                          originalNode={originalNode}
                                          reportNode={reportNode}
                                          routeData={routeData} >
                    {children}
                </RecordEditorMainInner>
                );
            }
        }
      </LibofLoadable>
  );
}

//右半边的子页面，编辑器页面，右半边页面的：
function RecordEditorMainInner( {queryRef, reportNode,originalNode, routeData,children}
        :{queryRef:RecordEditorMainInner$key, reportNode:any,originalNode:any, routeData:any,children: React.ReactNode}
) {
    //这个个RecordEditorPreviewInner  RecordEditorMainInner需要保持一致性的，都会传给原始记录主页面。
    const [data, refetch] = useRefetchableFragment(
        graphql`
            fragment RecordEditorMainInner on Query
            @refetchable(queryName: "RecordEditorMainInnerRefetch") {
                getReport(id: $id) {
                    id,version,type,tzFields,
                    data
                    snapshot
                    modeltype,modelversion,
                    isp{id,dev{id cod}
                        bus{id,
                        pipus{id crDate code rno name start stop nxtd1 nxtd2 leng level lay safe svp pa}
                    }}
                }
            }
        `,
        queryRef as RecordEditorMainInner$key,
    );
    const { getReport: items }=data;    //改成片段useRefetchableFragment所以挪动到了子组件来定义提取数据了。
    //【非常重要】不能用const mountedRef=useRef(items); if(mountedRef.current!==items){mountedRef.current=items; }来检测！mountedRef.current这里始终都会等于items的。Relay的原因吗！？？
    const context =React.useContext(EditStorageContext);
    if(context == null)    throw new Error("EditStorageContext没有提供");
    const {storage, setStorage} =context;
    console.log("仅切换了编辑区块链接跳转的竟然也执行: routeData=",routeData);
    //【特别大问题】 不能添加下面的副作用代码块。 多头状态修正管理有问题啊。
    // React.useEffect(() => {
    //     const  dat =items&&items.data&&JSON.parse(items.data);
    //     const  snap =items&&items.snapshot&&JSON.parse(items.snapshot);
    //         //已经确认的编辑区块数据 保留，对切换编辑器区块的影响多深？ 不同repId? 分项；
    //         // if(snap)   dat && setStorage({...dat, ...storage, ...snap, _version: items.version});
    //         // else  dat && setStorage({ ...dat, ...storage,  _version: items.version});
    //         // console.log("点击不同编辑区块跳转也都跑一趟啊:new",dat,"旧storage",storage);     //会导致编辑区块点击切换时刻没法保留上一个区块中确认的修改数据了！
    //     //已经确认的编辑区块数据 保留，对切换编辑器区块的影响多深？ 不同repId? 分项；
    //     if(snap)   dat && setStorage({...dat,  ...snap, _version: items.version});
    //     else  dat && setStorage({ ...dat,   _version: items.version});
    //     console.log("每一次路由routeData变动的这里都被执行",dat,"旧storage",storage);
    // }, []);

//【右半边】原始记录页面路由入口：
    return (
       <React.Fragment>
       { storage &&
              <RecordStarter  routeData={routeData}  ispId={items?.isp?.id!} refetch={refetch}
                                   rep={items}  prepared={ {source: storage, template: originalNode} } >
                    {children}
                </RecordStarter>
       }
       { !storage &&
           <div  css={[
                    {
                        display: 'flex',
                        alignItems:'center',
                        justifyContent:'center',
                        height: '100vh',
                    },
                ]}
           >
               <RouterLink href={`/inspect/${items?.isp?.id}/report/${items?.id}`}>
                 该报告的基础信息未赋值<hr/>还是返回报告摘要
               </RouterLink>
           </div>
       }
       </React.Fragment>
    );
}


// export default RecordEditorMain;
